﻿using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;

namespace HelenServer.Data.SqlServer;

public class EntityCollectionValueConverter<TContext, TEntity> : ValueConverter<ICollection<TEntity>, string>
    where TContext : DbContext
    where TEntity : class
{
    private static readonly TContext _context;

    static EntityCollectionValueConverter()
    {
        using var scope = Helen.Services.CreateScope();
        var factory = scope.ServiceProvider.GetRequiredService<IReadWriteSplittingDbContextFactory<TContext>>();

        var config = Helen.Services.GetRequiredService<IConfiguration>();
        var connectionString = config.GetConnectionString("master");

        _context = factory.Create(ReadWritePolicy.ReadWrite);

        AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
    }

    private static void CurrentDomain_ProcessExit(object? sender, EventArgs e)
    {
        _context?.Dispose();
    }

    public EntityCollectionValueConverter()
        : base(
              model => CompositId(model),
              provider => ConvertFromIds(provider))
    {

    }

    private static string CompositId(ICollection<TEntity> models)
    {
        var type = typeof(TEntity);

        var prop = type.GetProperty("Id") ?? throw new InvalidOperationException("模型必须具有属性Id");

        var temp = new List<string>();

        foreach (var model in models)
        {
            temp.Add(prop.GetValue(model)!.ToString()!);
        }

        return string.Join('#', temp);
    }

    private static ICollection<TEntity> ConvertFromIds(string provider)
    {
        if (string.IsNullOrEmpty(provider))
        {
            return new List<TEntity>();
        }

        var ids = provider.Split('#', StringSplitOptions.RemoveEmptyEntries);

        var models = new List<TEntity>();

        foreach (var id in ids)
        {
            models.Add(_context.Set<TEntity>().Find(id)!);
        }

        return models;
    }
}